#!/usr/bin/python

import sys
import re
from xml.dom import minidom
from config import *
from complements import *

class Documento:
    
    def create_tree(self, object):
        '''Crea un arbol de nodos con los atributos de la clase, 
        retorna el nodo padre'''
        node = self.document.createElement(self.childName)
        for tagname in object.ELEMENTS:
            self.add_element(node, tagname, getattr(object, tagname)) 
        return node

    def add_element(self, node, tagname, value = None):
        ''' Agrega un elemento y su valor a un nodo'''
        child = self.document.createElement(tagname)
        if value:
            text_value = self.document.createTextNode(value)
            child.appendChild(text_value)
        node.appendChild(child)
        return child

    def get_document(self, file):
        try: doc = minidom.parse(file)
        except:
            doc = minidom.Document()
            doc.appendChild(doc.createElement(self.myName))
        return doc

    def get_root_element(self):
        ''' Retorna el nodo principal del Documento'''   
        return self.document.documentElement

    def save_document(self, File):
        try:
            xmlfile = open(File, "w")       
        except:
            print "No se pudo guardar el archivo %s" % self.FILE
            return 
        xml = self.document.toxml(encoding=XML_ENCODING)
        xmlfile.write(xml)
        xmlfile.close()

    def get_all(self, tagname):
        ''' Retorna una lista con todos los nodos especificados en tagname '''
        return self.document.getElementsByTagName(tagname)

    def search(self, tagname, pattern):
        '''Busca coincidencias con pattern en los nodos especificados por tagname,
       retorna una lista con los elementos encontrados'''
        pattern = re.escape(pattern)
        found = []
        nodes = self.get_all(tagname)
        for node in nodes:
            value = self.get_text(node)
            if re.search("^%s.*" % pattern.upper(), value.upper()):
                found.append(node.parentNode)
        return found  

    def get_value(self, root, tagname):
        ''' Retorna el valor del primer elemento encontrado, 
            root es el nodo desde donde se buscara el elemento '''
        value = ""
        nodes = root.getElementsByTagName(tagname)
        if len(nodes) > 0:
            value = self.get_text(nodes[0])
        return value
        
    def get_text(self, node):
        ''' Retorna el valor de un nodo'''
        t = ''
        for child in node.childNodes:
            if child.nodeType == node.TEXT_NODE:
                t = t + child.data
        return t    
    
    def set_attributes(self, object):
        ''' Establece los atributos del objeto con los datos
        del Documento DOM '''
        for attr in object.ELEMENTS:
            setattr(object, attr, self.get_value(object.node, attr))

class Libreta(Documento):
    """ Crea un contenedor que almacena las cuentas o contactos
        y los guarda en un archivo XML, por default son los contactos"""
    
    def __init__(self, type='contactos', file=""):
        if type == 'contactos':
            self.childName = Contacto.elementName
            self.fileXml = FILE_LIBRETA
            self.myName = 'libreta'
        elif type == 'cuentas':
            self.childName = Cuenta.elementName
            self.fileXml = FILE_CUENTAS
            self.myName = 'cuentas'
        else: 
            print """No se puede crear una libreta con elementos %s,  
                solo pueden ser 'contactos' o 'cuentas'\n""" % type
        
        if file: self.fileXML = file
        self.document = self.get_document(self.fileXml)
        self.root = self.get_root_element()
 
    def get(self):
        list = []
        for node in self.get_all(self.childName):
            objChild = self.get_obj_child()    
            objChild.node = node
            self.set_attributes(objChild)
            list.append(objChild)
        return list    

    def append(self, objChild):
        node = self.create_tree(objChild)
        self.root.appendChild(node)
        self.save()
        return node
        
    def remove(self, objChild):
        try:
            self.root.removeChild(objChild.node)
            objChild.node.unlink()
            self.save()  
        except:
            print "No se pudo eliminar el/la %s" % self.myName
        
    def update(self, contacto):
        pass

    def search(self, name):
        ''' Busca los contacto que coincidan con el nombre'''
        list = []
        result = Documento.search(self, "nombre", name)
        for node in result:
            objChild = self.get_obj_child()
            objChild.node = node
            self.set_attributes(objChild)
            list.append(objChild)
        return list
    
    def get_obj_child(self):
        objChild = None
        if self.myName == 'libreta':
            objChild = Contacto()
        elif self.myName == 'cuentas':
            objChild = Cuenta()
        return objChild
        
    def save(self):
        self.save_document(self.fileXml)

    def  to_html(self):
        html = ViewHtml()
        html.set_title("Contactos")

        contactos = self.get()
        for con in contactos:
            elements = []
            for attr in con.ELEMENTS:
                if attr == "nombre":  title = getattr(con, attr)
                else:
                    list_values = (attr.capitalize(), getattr(con, attr))
                    elements.append(list_values)
            html.addgroup(title, elements)
        return html.document

    def to_xml(self):
        return self.document.toprettyxml(encoding=XML_ENCODING)

class Contacto:
    
    elementName = 'contacto'
    ELEMENTS = ["nombre", "direccion", "email", "msn",
                "nota", "telefono", "celular", "cumpleanios" ]
    
    def __init__(self):
        self.node = None
        self.nombre = ""
        self.direccion = ""
        self.email = ""
        self.msn = ""
        self.nota = ""
        self.telefono = ""
        self.celular = ""
        self.cumpleanios = ""

    def get_dia_cumpleanios(self):
        try: dia = self.cumpleanios.split("/")[0]
        except: dia = ""
        return dia

    def get_mes_cumpleanios(self):
        try: mes = self.cumpleanios.split("/")[1]
        except: mes = 0
        return int(mes)

class Cuenta:
    
    elementName= 'cuenta'
    ELEMENTS = ["nombre", "lugar", "clave", "descripcion", "email", "usuario" ]
    
    def __init__(self):
        self.node = None
        self.nombre = ""
        self.lugar = ""
        self.clave = ""
        self.descripcion = ""
        self.email = ""
        self.usuario = ""
        
    